import cgi
import os
import urllib
import logging
import model
import simplejson as json

from model import CrumbleUser
from model import ChatContent
from model import Greeting
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
from google.appengine.ext.webapp import template
from google.appengine.api import memcache

# Set the debug level
_DEBUG = True

def encode_response(obj):
    if isinstance(obj, CrumbleResponse):
      return {"gameUrl": obj.gameUrl,
              "moves": obj.moves,
              "lastMoveId": obj.lastMoveId,
              "users":obj.users,
              "whitePlayer":obj.whitePlayer,
              "blackPlayer":obj.blackPlayer,
              "status":obj.status,
              "error":obj.error
              }
    elif isinstance(obj, CrumbleResponseUser):
        return {"email": obj.email,
                "nickname": obj.nickname,
                "rating": obj.rating,
                "table_number": obj.table_number,
                "number_of_games_played":obj.number_of_games_played,
                "picture":obj.picture,
                "active":obj.active
               }


class CrumbleResponseUser(json.JSONEncoder):
  def __init__(self, user):
    self.email = user.email
    self.nickname = user.nickname
    self.rating = user.rating
    self.number_of_games_played = user.number_of_games_played
    self.joined = user.joined
    self.picture = user.picture
    self.active = user.active
    self.table_number = user.table_number
    logging.debug("#### WRITING RESOPONSE USER #####")
    s = json.dumps(self, default=encode_response)
    logging.debug(s)


class CrumbleResponse(json.JSONEncoder):
  def __init__(self):
    self.reset()

  def set_error(self, s):
    self.status = "error"
    self.error = s

  def reset(self):
    self.gameUrl = ""
    self.moves = {}
    self.lastMoveId = 0
    self.whitePlayer = ""
    self.blackPlayer = ""
    self.users = []
    self.status = "ok"
    self.error = ""

  def set_users(self, users):
    for user in users:
      self.users.append(CrumbleResponseUser(user))



class BaseRequestHandler(webapp.RequestHandler):
  """Base request handler extends webapp.Request handler

     It defines the generate method, which renders a Django template
     in response to a web request
  """
  crumble_user = None
  crumble_response = CrumbleResponse()

  def init_crumble_user(self):
    if not self.crumble_user:
      user = users.get_current_user()
      if user:
         self.crumble_user = model.get_crumble_user(user)

  def generate_right_page(self, table_number):
    if (table_number == None or table_number == ""):
      table_number = "0"
    logging.debug("generate_right_page for table " + table_number)
    self.init_crumble_user();
    template_values = {}
    if self.crumble_user:
      logging.debug("crumble user " + self.crumble_user.email)
      #TODO: move away from table, use table_number
      if table_number != "0":
        #template_values['table'] = model.get_updated_table(self.crumble_user.table_number)
        #self.generate('crumble.html', template_values);

        self.redirect('/room?table=' + table_number)
      else:
        logging.debug("sending user to room")
        template_values['new_table_url'] = "/newtable"
        self.generate('room.html', template_values);
    elif table_number == "0":
      # the user is not logged in, sent to a self-played game + login prompt
      self.generate('crumble2.html', template_values)
    else:
      logging.debug("table= " + table_number + ", user needs to log in first")
      logging.debug(self.request.path)
      # the user is not logged in, sent to a self-played game + login prompt
      self.redirect(users.create_login_url('/room?table=' + table_number))

  def generate(self, template_name, template_values={}):
    """Generate takes renders and HTML template along with values
       passed to that template

       Args:
         template_name: A string that represents the name of the HTML template
         template_values: A dictionary that associates objects with a string
           assigned to that object to call in the HTML template.  The defualt
           is an empty dictionary.
    """
    # We check if there is a current user and generate a login or logout URL
    user = users.get_current_user()

    logging.debug('generating room.html')
    if user:
      log_in_out_url = users.create_logout_url('/')
      self.crumble_user = model.get_crumble_user(user)
    else:
      log_in_out_url = users.create_login_url(self.request.path)

    # We'll display the user name if available and the URL on all pages
    values = {'user': user, 'log_in_out_url': log_in_out_url}
    values.update(template_values)

    # Construct the path to the template
    directory = os.path.dirname(__file__)
    path = os.path.join(directory, 'templates', template_name)

    # Respond to the request by rendering the template
    self.response.out.write(template.render(path, values, debug=_DEBUG))
    logging.debug("rendered page")

  def extract_params(self, value_string):
    pattern_string = self.parameterized_url()
    names = re.findall(r"\{(.*?)\}", pattern_string)
    regex = re.sub(r"\{.*?\}", r"([^/\?]*)", pattern_string)

    matcher = re.search(regex, value_string)

    if not matcher:
      return {}

    match = matcher.groups()
    result = {}
    for i in xrange(len(names)):
      if i > len(match):
        result[names[i]] = None
      else:
        result[names[i]] = match[i]

    return result

  def write_response(self):
    logging.debug("#### WRITING RESOPONSE #####")
    s = json.dumps(self.crumble_response, default=encode_response)
    logging.debug(s)
    self.response.out.write(s)
